package com.young.manager.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.young.common.execption.ServiceException;
import com.young.manager.mapper.SysMenuMapper;
import com.young.manager.mapper.SysRoleMenuMapper;
import com.young.manager.mapper.SysUserMapper;
import com.young.manager.mapper.SysUserRoleMapper;
import com.young.manager.model.SysMenu;
import com.young.manager.model.SysRoleMenu;
import com.young.manager.model.SysUser;
import com.young.manager.model.SysUserRole;
import com.young.manager.service.SysMenuService;
import java.util.Comparator;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;

@Slf4j
@RequiredArgsConstructor
@Service
public class SysMenuServiceImpl implements SysMenuService {

    private final SysMenuMapper sysMenuMapper;
    private final SysUserMapper sysUserMapper;
    private final SysRoleMenuMapper sysRoleMenuMapper;
    private final SysUserRoleMapper sysUserRoleMapper;

    @Override
    public List<SysMenu> queryList(String name, String mark, Long parentId) {
        QueryWrapper<SysMenu> queryWrapper = new QueryWrapper<>();
        if (StringUtils.hasLength(name)) queryWrapper.like("name", name);
        if (StringUtils.hasLength(mark)) queryWrapper.like("mark", mark);
        if (null != parentId) queryWrapper.eq("parent_id", parentId);
        queryWrapper.orderByAsc("sort");
        return sysMenuMapper.selectList(queryWrapper);
    }

    @Override
    public List<SysMenu> queryMenuTree() {
        List<SysMenu> allMenu = sysMenuMapper.selectList(null);
        return packageMenuTree(allMenu, 0L);
    }

    @Override
    public List<?> queryRoleMenuList(Long roleId, String column) {
        QueryWrapper<SysRoleMenu> queryWrapper = new QueryWrapper<>();
        queryWrapper.select("menu_id").eq("role_id", roleId);
        List<Long> menuIds = sysRoleMenuMapper.selectObjs(queryWrapper);
        if (null == column) {
            return sysMenuMapper.selectBatchIds(menuIds);
        } else if ("id".equals(column)) {
            return menuIds;
        } else if ("mark".equals(column)) {
            return sysMenuMapper.selectBatchIds(menuIds).stream().map(SysMenu::getMark).collect(Collectors.toList());
        }
        return Collections.EMPTY_LIST;
    }

    @Override
    public List<?> queryUserMenuList(Object userId) {
        if (null == userId) throw new ServiceException("参数缺失[userId]");
        // 先判断是否屎超级管理员
        SysUser sysUser = sysUserMapper.selectById(Long.parseLong(String.valueOf(userId)));
        if (sysUser.getSuperUser().equals(1)) {
            return sysMenuMapper.selectList(null).stream().map(SysMenu::getMark).collect(Collectors.toList());
        }
        QueryWrapper<SysUserRole> userRoleQueryWrapper = new QueryWrapper<>();
        userRoleQueryWrapper.select("role_id").eq("user_id", Long.parseLong(String.valueOf(userId)));
        List<Long> roleIds = sysUserRoleMapper.selectObjs(userRoleQueryWrapper);
        if (roleIds.isEmpty()) return Collections.EMPTY_LIST;
        QueryWrapper<SysRoleMenu> queryWrapper = new QueryWrapper<>();
        queryWrapper.select("menu_id").in("role_id", roleIds);
        List<Long> menuIds = sysRoleMenuMapper.selectObjs(queryWrapper);
        if (menuIds.isEmpty()) return Collections.EMPTY_LIST;
        return sysMenuMapper.selectBatchIds(menuIds).stream().map(SysMenu::getMark).collect(Collectors.toList());
    }

    @Override
    public void insertSysMenu(SysMenu menu) {
        String mark = menu.getMark();
        QueryWrapper<SysMenu> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("mark", mark);
        SysMenu exist = sysMenuMapper.selectOne(queryWrapper);
        if (null != exist) {
            throw new ServiceException("菜单标识已存在！");
        }
        Long parentId = menu.getParentId();
        if (null == parentId) {
            throw new ServiceException("参数缺失[parentId]！");
        }
        if (0 == parentId) {
            menu.setLevel(1);
        } else {
            SysMenu parentMenu = sysMenuMapper.selectById(parentId);
            menu.setLevel(parentMenu.getLevel() + 1);
        }
        sysMenuMapper.insert(menu);
    }

    @Override
    public void updateSysMenu(SysMenu menu) {
        if (null == menu.getId()) {
            throw new ServiceException("参数缺失[id]！");
        }
        String mark = menu.getMark();
        QueryWrapper<SysMenu> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("mark", mark);
        SysMenu exist = sysMenuMapper.selectOne(queryWrapper);
        if (null != exist && !exist.getId().equals(menu.getId())) {
            throw new ServiceException("菜单标识已存在！");
        }
        sysMenuMapper.updateById(menu);
    }

    @Override
    public void deleteSysMenu(Long id) {
        QueryWrapper<SysMenu> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("parent_id", id);
        List<SysMenu> children = sysMenuMapper.selectList(queryWrapper);
        if (!children.isEmpty()) throw new ServiceException("请先删除关联子菜单！");
        sysMenuMapper.deleteById(id);
    }

    private List<SysMenu> packageMenuTree(List<SysMenu> origin, Long parentId) {
        List<SysMenu> menuList = origin.stream().filter(it -> it.getParentId().equals(parentId)).sorted(
            Comparator.comparingInt(SysMenu::getSort)).collect(Collectors.toList());

        if (!menuList.isEmpty()) {
            menuList.forEach(t -> {
                List<SysMenu> children = packageMenuTree(origin, t.getId());
                t.setChildren(children);
            });
        }

        return menuList;
    }
}
